package com.docshell.common;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

import com.docshell.constants.DocShellConstants;
import com.docshell.exceptions.DocShellException;
import com.documentum.fc.client.IDfCollection;
import com.documentum.fc.common.DfAttr;
import com.documentum.fc.common.DfException;
import com.documentum.fc.common.IDfAttr;

public class DisplayManager {

	private static String m_Prompt = null;

	private static String m_inFile = null;
	private static String m_outFile = null;
	
	/** Writer */
	private static BufferedReader m_Reader;

	/** Reader */
	private static BufferedWriter m_Writer;	
	
	public static void initialize() throws DocShellException {
		try {
	
			InputStream instream = null;
			OutputStream outstream = null;			
			if (getinFile() != null) {
				instream = new FileInputStream(new File(getinFile()));
			} else {
				instream = System.in;
			}
			if (getoutFile() != null) {
				outstream = new FileOutputStream(new File(getoutFile()));
			} else {
				outstream = System.out;
			}			
			m_Reader = new BufferedReader(new InputStreamReader(instream));
			m_Writer = new BufferedWriter(new OutputStreamWriter(outstream));	
		}
		catch (Exception  ex) {
			throw new DocShellException(DocShellException.UNKNOWN_EXCEPTION, ex.toString());
		}
	}
	public static void setPrompt(String aPrompt) {
		DisplayManager.m_Prompt = aPrompt;
	}

	public static String getPrompt() {
		return m_Prompt;
	}
	
	public static void displayCollectionResult(IDfCollection collection) throws DocShellException {
		try {
			if (collection!=null ) {
				
				int colCount = collection.getAttrCount();
				IDfAttr [] loAttr = new IDfAttr[colCount];
				String lsAttrName = null;
				int attrWidth = 0;
				for (int counter=0; counter < colCount; counter++) {
					loAttr[counter] = collection.getAttr(counter);
					lsAttrName = loAttr[counter].getName().toString();
					if (loAttr[counter].getDataType()==DfAttr.DM_STRING) {
						attrWidth = loAttr[counter].getLength()<lsAttrName.length() ? lsAttrName.length() : loAttr[counter].getLength();
					}
					else if (loAttr[counter].getDataType()==DfAttr.DM_ID) {
						attrWidth = loAttr[counter].getLength();							
					}
					else if (loAttr[counter].getDataType()==DfAttr.DM_TIME) {
						attrWidth = lsAttrName.length()<22 ? 22 : lsAttrName.length();	
					}
					else if (loAttr[counter].getDataType()==DfAttr.DM_DOUBLE) {
						attrWidth = lsAttrName.length()<10 ? 10 : lsAttrName.length();	
					}
					else if (loAttr[counter].getDataType()==DfAttr.DM_INTEGER) {
						attrWidth = lsAttrName.length()<10 ? 10 : lsAttrName.length();	
					}
					else if (loAttr[counter].getDataType()==DfAttr.DM_BOOLEAN) {
						attrWidth = lsAttrName.length()<10 ? 10 : lsAttrName.length();							
					}
					writeColumn(lsAttrName, attrWidth);
				}
				m_Writer.write(DocShellConstants.NEWLINE_CHAR);
				for (int counter=0; counter < colCount; counter++) {
					lsAttrName = loAttr[counter].getName().toString();
					if (loAttr[counter].getDataType()==DfAttr.DM_STRING) {
						attrWidth = loAttr[counter].getLength()<lsAttrName.length() ? lsAttrName.length() : loAttr[counter].getLength();
					}
					else if (loAttr[counter].getDataType()==DfAttr.DM_ID) {
						attrWidth = loAttr[counter].getLength();							
					}
					else if (loAttr[counter].getDataType()==DfAttr.DM_TIME) {
						attrWidth = lsAttrName.length()<22 ? 22 : lsAttrName.length();	
					}
					else if (loAttr[counter].getDataType()==DfAttr.DM_DOUBLE) {
						attrWidth = lsAttrName.length()<10 ? 10 : lsAttrName.length();	
					}
					else if (loAttr[counter].getDataType()==DfAttr.DM_INTEGER) {
						attrWidth = lsAttrName.length()<10 ? 10 : lsAttrName.length();	
					}
					else if (loAttr[counter].getDataType()==DfAttr.DM_BOOLEAN) {
						attrWidth = lsAttrName.length()<10 ? 10 : lsAttrName.length();							
					}
					underLine(attrWidth);
				}
				m_Writer.write(DocShellConstants.NEWLINE_CHAR);
				m_Writer.flush();
				int rowCount=0;
				String lsValue = null;
				while (collection.next()) {
					for (int counter=0; counter < colCount; counter++) {
						lsAttrName = loAttr[counter].getName().toString();
						if (loAttr[counter].getDataType()==DfAttr.DM_STRING) {
							lsValue = collection.getString(loAttr[counter].getName().toString());
							attrWidth = loAttr[counter].getLength();
						}
						else if (loAttr[counter].getDataType()==DfAttr.DM_ID) {
							lsValue = collection.getId(loAttr[counter].getName().toString()).toString();
							attrWidth = loAttr[counter].getLength();							
						}
						else if (loAttr[counter].getDataType()==DfAttr.DM_TIME) {
							lsValue = collection.getTime(loAttr[counter].getName().toString()).toString();
							attrWidth = lsAttrName.length()<22 ? 22 : lsAttrName.length();	
						}
						else if (loAttr[counter].getDataType()==DfAttr.DM_DOUBLE) {
							lsValue = String.valueOf(collection.getDouble(loAttr[counter].getName().toString()));
							attrWidth = lsAttrName.length()<10 ? 10 : lsAttrName.length();	
						}
						else if (loAttr[counter].getDataType()==DfAttr.DM_INTEGER) {
							lsValue = String.valueOf(collection.getInt(loAttr[counter].getName().toString()));
							attrWidth = lsAttrName.length()<10 ? 10 : lsAttrName.length();	
						}
						else if (loAttr[counter].getDataType()==DfAttr.DM_BOOLEAN) {
							lsValue = String.valueOf(collection.getBoolean(loAttr[counter].getName().toString()));
							attrWidth = lsAttrName.length()<10 ? 10 : lsAttrName.length();							
						}
						
						writeColumn(lsValue, attrWidth);
					}
					m_Writer.write(DocShellConstants.NEWLINE_CHAR);
					m_Writer.flush();
					rowCount++;
				}
				writeLine(DocShellConstants.NEWLINE_CHAR + DocShellConstants.TAB_CHAR + rowCount + " object found!" + DocShellConstants.NEWLINE_CHAR);
				m_Writer.flush();
			}
		}
		catch (DfException dfe) {
			throw new DocShellException(DocShellException.DFC_EXCEPTION, dfe.toString());
		} catch (IOException ioex) {
			throw new DocShellException(DocShellException.IO_EXCEPTION, ioex.toString());
		} catch (Exception ex) {
			throw new DocShellException(DocShellException.UNKNOWN_EXCEPTION, ex.toString());
		}
	}

	public static void writeLine(String aMessage) throws DocShellException {
		try {
			m_Writer.write(aMessage + DocShellConstants.NEWLINE_CHAR);
			m_Writer.flush();
		} catch (IOException ioex) {
			throw new DocShellException(DocShellException.IO_EXCEPTION, ioex.toString());
		} catch (Exception ex) {
			throw new DocShellException(DocShellException.UNKNOWN_EXCEPTION, ex.toString());
		}
	}

	public static void write(String aMessage) throws DocShellException {
		try {
			m_Writer.write(aMessage);
			m_Writer.flush();
		} catch (IOException ioex) {
			throw new DocShellException(DocShellException.IO_EXCEPTION, ioex.toString());
		} catch (Exception ex) {
			throw new DocShellException(DocShellException.UNKNOWN_EXCEPTION, ex.toString());
		}
	}
	
	public static void writeColumn(String message, int width) throws DocShellException {
		String lsMessage = null;
		if (width>DocShellConstants.MAX_COLUMN_WIDTH) width=DocShellConstants.MAX_COLUMN_WIDTH;
		lsMessage = message + DocShellConstants.EMPTY_SPACE.substring(0,width-message.length());
		try {
			m_Writer.write(lsMessage + DocShellConstants.TAB_CHAR);
		} catch (IOException e) {
			throw new DocShellException(DocShellException.IO_EXCEPTION, e.toString());
		}
	}
	
	public static void underLine(int width) throws DocShellException {
		String lsMessage = null;
		if (width>DocShellConstants.MAX_COLUMN_WIDTH) width=DocShellConstants.MAX_COLUMN_WIDTH;
		lsMessage = DocShellConstants.UNDERLINE_STRING.substring(0,width);
		try {
			m_Writer.write(lsMessage + DocShellConstants.TAB_CHAR);
		} catch (IOException e) {
			throw new DocShellException(DocShellException.IO_EXCEPTION, e.toString());
		}
	}
	
	public static void setinFile(String m_inFile) {
		DisplayManager.m_inFile = m_inFile;
	}
	
	public static String getinFile() {
		return m_inFile;
	}
	
	public static void setoutFile(String m_outFile) {
		DisplayManager.m_outFile = m_outFile;
	}
	
	public static String getoutFile() {
		return m_outFile;
	}

	public static String getLine() throws IOException {
		m_Writer.write(getPrompt()+"> ");
		m_Writer.flush();
		return m_Reader.readLine();
	}
}
